#include "Inventory.h"

int Inventory::quantity(string name, Type type) {
	int quantity = 0;

	for(size_t i = 0; i < items.size(); i++) {
		if(items[i].getName() == name && items[i].getItemType() == type)
			quantity++;
	}

	return quantity;
}

void Inventory::updateQuantity(string name, Type type, int quantity) {
	for(size_t i = 0; i < items.size(); i++) {
			if(items[i].getName() == name && items[i].getItemType() == type)
				items[i].setQuantity(quantity);
		}
}

void Inventory::initializeItemsQuantity() {
	for(size_t i = 0; i < items.size(); i++) {
		int _quantity = quantity(items[i].getName(), items[i].getItemType());
		items[i].setQuantity(_quantity);
	}
}

void Inventory::updateItemPrice(Item item) {
	int quant = quantity(item.getName(), item.getItemType());

	for(size_t i = 0; i < items.size(); i++) {
		if(items[i].getID() == item.getID())
			item.updatePrice(quant);
	}
}

void Inventory::createItem(string _owner) {
	cout << "\n\t\t== Add New Item ==\n" << endl;
	cout << "Name: ";
	string name;
	fflush(stdin);
	getline(cin, name);

	cout << "1) Choose available type" << endl;
	cout << "2) Add new type" << endl;
	cout << "3) Exit" << endl << endl;

	int option = manageOptions(3);

	//Invalid option
	while (option == -1) {
		string temp = "";
		getline(cin, temp);
		option = manageOptions(3);
	}

	Type newType;

	if (option == 1) {

		size_t index = 1;

		// show all types
		for (size_t i = 0; i < types.size(); i++) {
			cout << index << ")";
			types[i].showType();
			index++;
		}

		// chose from all types using the index of the vector
		int option = manageOptions(types.size());

		//Invalid option
		while (option == -1) {
			string temp = "";
			getline(cin, temp);
			option = manageOptions(types.size());
		}

		newType = types[option - 1];

	} else if (option == 2) {
		string _maintype;
		string _subtype;
		cout << "Insert a maintype: ";
		fflush(stdin);
		getline(cin, _maintype);
		cout << "Insert a subtype: ";
		fflush(stdin);
		getline(cin, _subtype);

		newType = Type(_maintype, _subtype);

		bool _typeExists = typeExists(newType);

		if (_typeExists == false) {
			addType(newType);
		}
	} else if (option == 3) {
		return;
	}

	cout << "Price: ";
	string price_str;
	fflush(stdin);
	getline(cin, price_str);

	float price = (float) atof(price_str.c_str());

	if(price == 0)
		price = 1;

	cout << "Insert the item's crafting date" << endl;
	string _age_minutes, _age_hour, _age_day, _age_month, _age_year;

	cout << "Insert minutes: ";
	fflush(stdin);
	getline(cin, _age_minutes);

	cout << "Insert hour: ";
	fflush(stdin);
	getline(cin, _age_hour);

	cout << "Insert day: ";
	fflush(stdin);
	getline(cin, _age_day);

	cout << "Insert month: ";
	fflush(stdin);
	getline(cin, _age_month);

	cout << "Insert year: ";
	fflush(stdin);
	getline(cin, _age_year);

	bool b_age = isNotNumber(_age_minutes) ||
				isNotNumber(_age_hour) ||
				isNotNumber(_age_day) ||
				isNotNumber(_age_month) ||
				isNotNumber(_age_year);

	if (b_age) {
		cout << "Invalid parameter (not digits)" << endl;
		return;
	}

	int age_minutes = atoi(_age_minutes.c_str());
	int age_hour = atoi(_age_hour.c_str());
	int age_day = atoi(_age_day.c_str());
	int age_month = atoi(_age_month.c_str());
	int age_year = atoi(_age_year.c_str());

	Date age(age_minutes, age_hour, age_day, age_month, age_year);

	Item newItem(name, _owner, newType, age, price);

	try{
		addItem(newItem);
		updateRareItems();
	} catch (ExistentItem &e) {
		cout << "Item already exists!";
	}
}

bool Inventory::typeExists(Type _type) {
	for (size_t i = 0; i < types.size(); i++) {
		if (types[i] == _type)
			return true;
	}
	return false;
}

void Inventory::setItem(Item _item) {
	for(size_t i = 0; i < items.size(); i++) {
		if (items[i].getID() == _item.getID())
			items[i] = _item;
	}
}

void Inventory::addItem(Item item) {

	bool sameItem = false;
	string name = item.getName();
	Type itemType = item.getItemType();

	for (size_t i = 0; i < items.size(); i++) {
		if (items[i] == item)
			throw ExistentItem();

		// if we want to add an unit to the quantity of an existent item, the quantity is updated
		if ((name == items[i].getName())
				&& (itemType == items[i].getItemType())) {
			sameItem = true;
			break;
		}
	}

	int _quantity = quantity(name, itemType);

	if (sameItem == true)
	{
		item.setQuantity(_quantity + 1);
		updateQuantity(name, itemType, _quantity + 1);
	}
	else
		item.setQuantity(1);

	items.push_back(item);
}

void Inventory::removeItem(Item* _item) {

	cout << "Are you sure you want to delete this item?  (Y/y - Yes; Any other char - No)"
			<< endl;
	char answer;
	cin.clear();
	cin >> answer;

	if (answer == 'Y' || answer == 'y') {

		int index = -1;

		for (size_t i = 0; i < items.size(); i++) {
			unsigned int _ID = _item->getID();
			if (_ID == items[i].getID()) {
				index = i;
			}
		}

		if (index != -1) {

			string name = _item->getName();
			Type itemType = _item->getItemType();
			bool sameItem = false;

			for (size_t i = 0; i < items.size(); i++) {

				// if we want to erase an unit to the quantity of an existent item, the quantity is updated
				if ((name == items[i].getName())
						&& (itemType == items[i].getItemType())) {
					sameItem = true;
					break;
				}
			}

			int _quantity = quantity(name, itemType);

			if (sameItem == true) {
				_item->setQuantity(_quantity - 1);
				updateQuantity(name, itemType, _quantity - 1);
			}

			items.erase(items.begin() + index);
			cout << "Item successfully deleted!\n" << endl;
		}
	}
	else
	{
		cout << "Item not deleted!\n" << endl;
	}
}

void Inventory::addType(Type type) {
	types.push_back(type);
}


vector<string> Inventory::uniqueMaintypes() {

	vector<string> maintypes;
	vector<string> uniqueMaintypes;

	for(size_t i = 0; i < types.size(); i++)
	{
		string _maintype = types[i].getMaintype();
		maintypes.push_back(_maintype);
	}
	uniqueMaintypes.push_back(maintypes[0]);

	for(size_t i = 0; i < maintypes.size(); i++)
	{
		bool exists = false;

		string _maintype = maintypes[i];

		for (size_t j = 0; j < uniqueMaintypes.size(); j++) {

			if (_maintype == uniqueMaintypes[j]) {
				exists = true;
				break;
			}
		}


		if(exists == false)
		{
			uniqueMaintypes.push_back(_maintype);
		}
	}

	return uniqueMaintypes;

}

vector<string> Inventory::uniqueSubtypes() {

	vector<string> subtypes;
		vector<string> uniqueSubtypes;

		for(size_t i = 0; i < types.size(); i++)
		{
			string _subtype = types[i].getSubtype();
			subtypes.push_back(_subtype);
		}
		uniqueSubtypes.push_back(subtypes[0]);

		for(size_t i = 0; i < subtypes.size(); i++)
		{
			string _subtype = subtypes[i];
			bool exists = false;

			for(size_t j = 0; j < uniqueSubtypes.size(); j++)
			{
				if(_subtype == uniqueSubtypes[j])
					exists = true;
			}

			if(exists == false)
			{
				uniqueSubtypes.push_back(_subtype);
			}
		}

		return uniqueSubtypes;
}

void Inventory::showInventory() {

	cout << "\n\t\t== All Items ==\n" << endl;
	for (size_t i = 0; i < items.size(); i++) {
		items[i].showItem();
	}
	cout << endl;
}

void Inventory::showInventory(Client* _client) {

	bool found = false;
	string _clientID = _client->getID();

	cout << "\n\t\t== Items ==\n" << endl;

	for (size_t i = 0; i < items.size(); i++) {
		string _owner = items[i].getOwner();
		if (_owner == _clientID) {
			items[i].showItem();
			found = true;
		}
	}

	cout << endl;

	if(found == false)
	{
		cout << "\t\tNo items found.\n" << endl;
	}
}

void Inventory::showItems(vector<Item*> _items) {

	for (size_t i = 0; i < _items.size(); i++) {
		cout << i+1 << ") " << endl;
		_items[i]->showItem();
	}
	cout << endl;
}

void Inventory::showTypes() {

	for (size_t i = 0; i < types.size(); i++) {
		cout << i+1 << ") " << endl;
		types[i].showType();
	}
	cout << endl;
}

void Inventory::editItemType()
{
	int index = chosenType();

	cout << "\t\t== Edit Item Type ==\n" << endl;
	cout << "1) Edit maintype" << endl;
	cout << "2) Edit subtype" << endl << endl;

	cout << "3) Return" << endl << endl;

	Type chosenType = types[index];
	Type* chosenTypeP = &(types[index]);

	int option = manageOptions(3);

			//Invalid option
			while (option == -1) {
				string temp = "";
				getline(cin, temp);
				option = manageOptions(3);
			}

			// Edit Maintype
			if(option == 1)
			{
				cout << "Current maintype: " << chosenType.getMaintype() << endl;
				cout << "New maintype: ";
				string _maintype;
				fflush(stdin);
				getline(cin, _maintype);
				chosenTypeP->setMaintype(_maintype);
				cout << "Maintype successfully changed!\n" << endl;
			}
			// Edit Subtype
			else if(option == 2)
			{
				cout << "Current subtype: " << chosenType.getSubtype() << endl;
				cout << "New subtype: ";
				string _subtype;
				fflush(stdin);
				getline(cin, _subtype);
				chosenTypeP->setSubtype(_subtype);
				cout << "Subtype successfully changed!\n" << endl;
			}
			// Return
			else if (option == 3)
			{
				return;
			}
}

void Inventory::deleteItemType() {
	int index = chosenType();

	types.erase(types.begin() + index);

	cout << "Type successfully deleted!\n" << endl;
}

int Inventory::chosenType() {
	cout << "\n\t\t== Chose an item type ==\n"<< endl;
		showTypes();

		int option = manageOptions(types.size());

				//Invalid option
				while (option == -1) {
					string temp = "";
					getline(cin, temp);
					option = manageOptions(types.size());
				}

				int chosenType = option - 1;

				return chosenType;
}

vector<Item*> Inventory::itemsP() {

	vector<Item*> _items;

	if (items.size() > 0) {

		for (size_t i = 0; i < items.size(); i++) {
				_items.push_back(&items[i]);
		}

	}
	return _items;
}

Item Inventory::searchItemByID(unsigned int itemID) {
	for (size_t i = 0; i < items.size(); i++) {
		if (items[i].getID() == itemID)
			return items[i];
	}

	throw NonexistentItem();
}

vector<Item*> Inventory::itemsSearch() {

	vector<Item*> itemsFound;

	cout << "\t\t== Search Item By Name ==\n" << endl;
	cout << "Insert word or letter to search: ";
	string strToSearch;
	fflush(stdin);
	getline(cin, strToSearch);
	strToSearch = toUpper(strToSearch); // convert strToSearch to upper case

	cout << "\n\t\t== Items Found ==\n" << endl;
	for (size_t i = 0; i < items.size(); i++) {

		string _name = items[i].getName();
		_name = toUpper(_name); // convert _name to upper case

		// find if the strToSearch is included in _name
		if (_name.find(strToSearch) != string::npos) {
			itemsFound.push_back(&items[i]);
		}
	}

	if(itemsFound.size() == 0)
		throw NonexistentItem();

	return itemsFound;
}

vector<Item*> Inventory::itemsSearchByMaintype() {
	vector<Item*> itemsFound;

	cout << "\t\t== Search Item By Maintype ==\n" << endl;
	cout << "1) List of all maintypes" << endl;
	cout << "2) Search maintypes" << endl << endl;

	cout << "3) Return" << endl << endl;

	int option1 = manageOptions(3);

	//Invalid option
	while (option1 == -1) {
		string temp = "";
		getline(cin, temp);
		option1 = manageOptions(3);
	}

	//if the option picked is valid
	// List of all maintypes
	if(option1 == 1) {

		vector<string> maintypes = uniqueMaintypes();

		cout << "\n\t\t== Maintypes ==\n" << endl;
		for (size_t i = 0; i < maintypes.size(); i++) {
			cout << i + 1 << ") " << maintypes[i] << endl;
		}
		cout << endl;

		cout << "\t\t== Chose Maintype ==\n" << endl;
		int option2 = manageOptions(maintypes.size());

		//Invalid option
		while (option2 == -1) {
			string temp = "";
			getline(cin, temp);
			option2 = manageOptions(maintypes.size());
		}

		string chosenMaintype = maintypes[option2 - 1];
		chosenMaintype = toUpper(chosenMaintype);

		cout << "\n\t\t== Items Found ==\n" << endl;
		for (size_t i = 0; i < items.size(); i++) {
			Type _type = items[i].getItemType();
			string _maintype = _type.getMaintype();
			_maintype = toUpper(_maintype); // convert _maintype to upper case

			// find if the chosenMaintype is included in _maintype
			if (_maintype.find(chosenMaintype) != string::npos) {
				itemsFound.push_back(&items[i]);
			}
		}

		if(itemsFound.size() == 0)
			throw NonexistentItem();


	}
	// Search maintypes
	else if (option1 == 2) {
		cout << "Insert word or letter to search: ";
		string strToSearch;
		fflush(stdin);
		getline(cin, strToSearch);
		strToSearch = toUpper(strToSearch); // convert strToSearch to upper case

		cout << "\n\t\t== Items Found ==\n" << endl;
		for (size_t i = 0; i < items.size(); i++) {
			Type _type = items[i].getItemType();
			string _maintype = _type.getMaintype();
			_maintype = toUpper(_maintype); // convert _maintype to upper case

			// find if the strToSearch is included in _maintype
			if (_maintype.find(strToSearch) != string::npos) {
				itemsFound.push_back(&items[i]);
			}
		}

		if(itemsFound.size() == 0)
			throw NonexistentItem();
	}

	return itemsFound;
}

vector<Item*> Inventory::itemsSearchBySubtype() {
	vector<Item*> itemsFound;

	cout << "\t\t== Search Item By Subtype ==\n" << endl;
	cout << "1) List of all subtypes" << endl;
	cout << "2) Search subtypes" << endl << endl;

	cout << "3) Return" << endl << endl;

	int option1 = manageOptions(3);

	//Invalid option
	while (option1 == -1) {
		string temp = "";
		getline(cin, temp);
		option1 = manageOptions(3);
	}

	//if the option picked is valid
	// List of all subtypes
	if(option1 == 1) {

		vector<string> subtypes = uniqueSubtypes();

		cout << "\n\t\t== Subtypes ==\n" << endl;
		for (size_t i = 0; i < subtypes.size(); i++) {
			cout << i + 1 << ") " << subtypes[i] << endl;
		}
		cout << endl;

		cout << "\t\t== Chose Subtype ==\n" << endl;
		int option2 = manageOptions(subtypes.size());

		//Invalid option
		while (option2 == -1) {
			string temp = "";
			getline(cin, temp);
			option2 = manageOptions(subtypes.size());
		}

		string chosenSubtype = subtypes[option2 - 1];
		chosenSubtype = toUpper(chosenSubtype);

		cout << "\n\t\t== Items Found ==\n" << endl;
		for (size_t i = 0; i < items.size(); i++) {
			Type _type = items[i].getItemType();
			string _subtype = _type.getSubtype();
			_subtype = toUpper(_subtype); // convert _subtype to upper case

			// find if the chosenSubtype is included in _maintype
			if (_subtype.find(chosenSubtype) != string::npos) {
				itemsFound.push_back(&items[i]);
			}
		}

		if(itemsFound.size() == 0)
			throw NonexistentItem();
	}
	// Search subtypes
	else if (option1 == 2) {
		cout << "Insert word or letter to search: ";
		string strToSearch;
		fflush(stdin);
		getline(cin, strToSearch);
		strToSearch = toUpper(strToSearch); // convert strToSearch to upper case

		cout << "\n\t\t== Items Found ==\n" << endl;
		for (size_t i = 0; i < items.size(); i++) {
			Type _type = items[i].getItemType();
			string _subtype = _type.getSubtype();
			_subtype = toUpper(_subtype); // convert _maintype to upper case

			// find if the strToSearch is included in _maintype
			if (_subtype.find(strToSearch) != string::npos) {
				itemsFound.push_back(&items[i]);
			}
		}

		if(itemsFound.size() == 0)
			throw NonexistentItem();
	}


	if (itemsFound.size() == 0) {
		cout << "No items found.\n" << endl;
	}

	return itemsFound;
}

vector<Item*> Inventory::itemsSearchByID() {
	vector<Item *> itemsFound;

	cout << "\t\t== Search Item By ID ==\n" << endl;

	unsigned int itemID;

	bool validOp = false; // variable that is true when "itemID" is in a valid format

	cout << "Insert the ID to search: ";
	// check for valid input
	do {
		cin >> itemID;

		// if the input is valid the loop stops
		if (cin.good()) {
			validOp = true;
		} else {
			cout << "Invalid ID! (it can only contain numbers)" << endl;
			cout << "Insert the ID to search: ";

			// clear the input
			cin.clear();
			cin.sync();
		}

	} while (validOp == false);

	cout << "\n\t\t== Items Found ==\n" << endl;

	for (size_t i = 0; i < items.size(); i++) {
		if (items[i].getID() == itemID) {
			itemsFound.push_back(&(items[i]));
		}
	}

	if(itemsFound.size() == 0)
		throw NonexistentItem();

	return itemsFound;
}

vector<Item*> Inventory::itemsSearchByAge() {
	vector<Item*> itemsFound;

	cout << "\t\t== Search Item By Age ==\n" << endl;
	cout << "1) List of all ages" << endl;
	cout << "2) Search ages" << endl;
	cout << "3) Search between age1 and age2" << endl << endl;

	cout << "4) Return" << endl << endl;

	int option1 = manageOptions(4);

	//Invalid option
	while (option1 == -1) {
		string temp = "";
		getline(cin, temp);
		option1 = manageOptions(4);
	}

	//if the option picked is valid
	// List of all ages
	if(option1 == 1) {
		vector<Date> ages;

		for(size_t a = 0; a < items.size(); a++) {
			ages.push_back(items[a].getAge());
		}

		cout << "\n\t\t== Item Crafting Dates (Ages) ==\n" << endl;
		for (size_t i = 0; i < ages.size(); i++) {
			cout << i + 1 << ") ";
			ages[i].displayDate();
			cout << endl;
		}
		cout << endl;

		cout << "\t\t== Chose Crafting Date (Age) ==\n" << endl;
		int option2 = manageOptions(ages.size());

		//Invalid option
		while (option2 == -1) {
			string temp = "";
			getline(cin, temp);
			option2 = manageOptions(ages.size());
		}

		Date chosenDate = ages[option2 - 1];

		cout << "\n\t\t== Items Found ==\n" << endl;
		for (size_t i = 0; i < items.size(); i++) {
			if (chosenDate == items[i].getAge()) {
				itemsFound.push_back(&items[i]);
			}
		}

		if(itemsFound.size() == 0)
			throw NonexistentItem();
	}
	// Search ages
	else if (option1 == 2) {
		cout << "Insert the crafting date (age)" << endl;
		string _age_minutes, _age_hour, _age_day, _age_month, _age_year;

		cout << "Insert minutes: ";
		fflush(stdin);
		getline(cin, _age_minutes);

		cout << "Insert hour: ";
		fflush(stdin);
		getline(cin, _age_hour);

		cout << "Insert day: ";
		fflush(stdin);
		getline(cin, _age_day);

		cout << "Insert month: ";
		fflush(stdin);
		getline(cin, _age_month);

		cout << "Insert year: ";
		fflush(stdin);
		getline(cin, _age_year);

		bool b_age = isNotNumber(_age_minutes) ||
				isNotNumber(_age_hour) ||
				isNotNumber(_age_day) ||
				isNotNumber(_age_month) ||
				isNotNumber(_age_year);

		if (b_age) {
			cout << "Invalid parameter (not digits)" << endl;
			return itemsFound;
		}

		int age_minutes = atoi(_age_minutes.c_str());
		int age_hour = atoi(_age_hour.c_str());
		int age_day = atoi(_age_day.c_str());
		int age_month = atoi(_age_month.c_str());
		int age_year = atoi(_age_year.c_str());

		Date age(age_minutes, age_hour, age_day, age_month, age_year);

		cout << "\n\t\t== Items Found ==\n" << endl;
		for (size_t i = 0; i < items.size(); i++) {
			if (age == items[i].getAge()) {
				itemsFound.push_back(&items[i]);
			}
		}

		if(itemsFound.size() == 0)
			throw NonexistentItem();
	}
	// Search between age1 and age2
	else if(option1 == 3) {
		cout << "Items will be searched between age1 and age2! Age1 and Age2 will be included as well." << endl;
		cout << "Insert the crafting date 1 (age1)" << endl;
		string _age_minutes, _age_hour, _age_day, _age_month, _age_year;

		cout << "Insert minutes: ";
		fflush(stdin);
		getline(cin, _age_minutes);

		cout << "Insert hour: ";
		fflush(stdin);
		getline(cin, _age_hour);

		cout << "Insert day: ";
		fflush(stdin);
		getline(cin, _age_day);

		cout << "Insert month: ";
		fflush(stdin);
		getline(cin, _age_month);

		cout << "Insert year: ";
		fflush(stdin);
		getline(cin, _age_year);

		bool b_age = isNotNumber(_age_minutes) ||
				isNotNumber(_age_hour) ||
				isNotNumber(_age_day) ||
				isNotNumber(_age_month) ||
				isNotNumber(_age_year);

		if (b_age) {
			cout << "Invalid parameter (not digits)" << endl;
			return itemsFound;
		}

		int age_minutes = atoi(_age_minutes.c_str());
		int age_hour = atoi(_age_hour.c_str());
		int age_day = atoi(_age_day.c_str());
		int age_month = atoi(_age_month.c_str());
		int age_year = atoi(_age_year.c_str());

		Date age1(age_minutes, age_hour, age_day, age_month, age_year);

		cout << "Insert the crafting date 2 (age2)" << endl;
		cout << "Insert minutes: ";
		fflush(stdin);
		getline(cin, _age_minutes);

		cout << "Insert hour: ";
		fflush(stdin);
		getline(cin, _age_hour);

		cout << "Insert day: ";
		fflush(stdin);
		getline(cin, _age_day);

		cout << "Insert month: ";
		fflush(stdin);
		getline(cin, _age_month);

		cout << "Insert year: ";
		fflush(stdin);
		getline(cin, _age_year);

		b_age = isNotNumber(_age_minutes) ||
				isNotNumber(_age_hour) ||
				isNotNumber(_age_day) ||
				isNotNumber(_age_month) ||
				isNotNumber(_age_year);

		if (b_age) {
			cout << "Invalid parameter (not digits)" << endl;
			return itemsFound;
		}

		age_minutes = atoi(_age_minutes.c_str());
		age_hour = atoi(_age_hour.c_str());
		age_day = atoi(_age_day.c_str());
		age_month = atoi(_age_month.c_str());
		age_year = atoi(_age_year.c_str());

		Date age2(age_minutes, age_hour, age_day, age_month, age_year);

		cout << "\n\t\t== Items Found ==\n" << endl;
		for (size_t i = 0; i < items.size(); i++) {
			if (age1 <= items[i].getAge() && age2 >= items[i].getAge()) {
				itemsFound.push_back(&items[i]);
			}
		}

		if(itemsFound.size() == 0)
			throw NonexistentItem();
	}

	return itemsFound;
}

vector <Item*> Inventory::itemsSearchByPrice() {
	vector<Item*> itemsFound;

	//price range options:
	//	below given price, equal to given price, higher than given price, between given prices
	cout << "\t\t== Search Item By Price ==\n" << endl;
	cout << "1) List of all prices" << endl;
	cout << "2) Search prices" << endl;
	cout << "3) Search below selected price" << endl;
	cout << "4) Search between price1 and price2" << endl;
	cout << "5) Search for higher prices" << endl << endl;

	cout << "6) Return" << endl << endl;

	int option1 = manageOptions(6);

	//Invalid option
	while (option1 == -1) {
		string temp = "";
		getline(cin, temp);
		option1 = manageOptions(6);
	}

	//if the option picked is valid
	// List of all prices
	if(option1 == 1) {
		vector<float> prices;

		for(size_t a = 0; a < items.size(); a++) {
			prices.push_back(items[a].getPrice());
		}

		cout << "\n\t\t== Item Prices ==\n" << endl;
		for (size_t i = 0; i < prices.size(); i++) {
			cout << i + 1 << ") " << prices[i] << endl;
		}
		cout << endl;

		cout << "\t\t== Choose Price ==\n" << endl;
		int option2 = manageOptions(prices.size());

		//Invalid option
		while (option2 == -1) {
			string temp = "";
			getline(cin, temp);
			option2 = manageOptions(prices.size());
		}

		float chosenPrice = prices[option2 - 1];

		cout << "\n\t\t== Items Found ==\n" << endl;
		for (size_t i = 0; i < items.size(); i++) {
			if (chosenPrice == items[i].getPrice()) {
				itemsFound.push_back(&items[i]);
			}
		}

		if(itemsFound.size() == 0)
			throw NonexistentItem();
	}
	// Search prices
	else if (option1 == 2) {
		cout << "Insert the price" << endl;
		string price_str;
		float price;

		bool b_price = isNotNumber(price_str);

		if (b_price) {
			cout << "Invalid parameter (not digits)" << endl;
			return itemsFound;
		}

		price = atof(price_str.c_str());

		if(price == 0)
			price = 1;

		cout << "\n\t\t== Items Found ==\n" << endl;
		for (size_t i = 0; i < items.size(); i++) {
			if (price == items[i].getPrice()) {
				itemsFound.push_back(&items[i]);
			}
		}

		if(itemsFound.size() == 0)
			throw NonexistentItem();
	}
	// Search below selected price
	else if(option1 == 3) {
		cout << "Insert the price" << endl;
		string price_str;
		float price;

		bool b_price = isNotNumber(price_str);

		if (b_price) {
			cout << "Invalid parameter (not digits)" << endl;
			return itemsFound;
		}

		price = atof(price_str.c_str());

		if(price == 0)
			price = 1;

		cout << "\n\t\t== Items Found ==\n" << endl;
		for (size_t i = 0; i < items.size(); i++) {
			if (price > items[i].getPrice()) {
				itemsFound.push_back(&items[i]);
			}
		}

		if(itemsFound.size() == 0)
			throw NonexistentItem();
	}
	// Search between price1 and price2
	else if(option1 == 4) {
		cout << "Items will be searched between price1 and price2! Price1 and price2 will be included as well." << endl;
		string price1_str, price2_str;
		float price1, price2;

		cout << "Insert price 1: " << endl;
		fflush(stdin);
		getline(cin, price1_str);

		cout << "Insert price 2: ";
		fflush(stdin);
		getline(cin, price2_str);

		bool b_price = isNotNumber(price1_str) || isNotNumber(price2_str);

		if (b_price) {
			cout << "Invalid parameter (not digits)" << endl;
			return itemsFound;
		}

		price1 = atof(price1_str.c_str());
		price2 = atof(price2_str.c_str());

		if(price1 == 0)
			price1 = 1;

		if(price2 == 0)
			price2 = 1;

		cout << "\n\t\t== Items Found ==\n" << endl;
		for (size_t i = 0; i < items.size(); i++) {
			if (price1 <= items[i].getPrice() && price2 >= items[i].getPrice()) {
				itemsFound.push_back(&items[i]);
			}
		}

		if(itemsFound.size() == 0)
			throw NonexistentItem();
	}
	// Search for higher prices
	else if(option1 == 5) {
		cout << "Insert the price" << endl;
		string price_str;
		float price;

		bool b_price = isNotNumber(price_str);

		if (b_price) {
			cout << "Invalid parameter (not digits)" << endl;
			return itemsFound;
		}

		price = atof(price_str.c_str());

		if(price == 0)
			price = 1;

		cout << "\n\t\t== Items Found ==\n" << endl;
		for (size_t i = 0; i < items.size(); i++) {
			if (price < items[i].getPrice()) {
				itemsFound.push_back(&items[i]);
			}
		}

		if(itemsFound.size() == 0)
			throw NonexistentItem();
	}

	return itemsFound;
}

vector <Item*> Inventory::getClientItems(Client* _client) {
	vector <Item*> _clientItems;

	for (size_t i = 0; i < items.size(); i++) {

		string _owner = items[i].getOwner();

		if (_owner == _client->getID()) {
			_clientItems.push_back(&items[i]);
		}
	}

	return _clientItems;
}

void Inventory::initializeRareItems() {
	for(size_t i = 0; i < items.size(); i++)
	{
		rareItems.push(&items[i]);
	}
}

void Inventory::updateRareItems() {
       rareItems.push(&(items.back()));
}

void Inventory::removeFromRareItems(Item* _item) {
       priority_queue<Item*, vector<Item*>, compareItems> aux;

       while(!rareItems.empty()) {
               if(rareItems.top()->getID() == _item->getID()) {
                       rareItems.pop();
               }

               aux.push(rareItems.top());
               rareItems.pop();
       }

       while(!aux.empty()) {
               rareItems.push(aux.top());
               aux.pop();
       }

}
